<?php

//__tostring()
//当对象被当做String使用时，这个方法会被自动调用  即echo $obj
//
//__invoke()
//当对象被当成方法调用时，这个方法会被自动调用  即$obj(4)


//__call()
//当对象访问不存在的方法名称时，__call()方法会被自动调用
//
//__callStatic()
//当对象访问不存在的静态方法名称时，__callStatic()方法会被自动调用
//
//通过这两个方法，同一个方法名称的调用可以对应不同的方法实现



//__set()
//在给不可访问属性赋值时，__set()会被调用
//
//__get()
//读取不可访问属性的值时，__get()会被调用
//
//__isset()
//当对不可访问属性调用isset()或empty()时，__isset()会被调用
//
//__unset()
//当对不可访问属性调用unset()时，__unset()会被调用
//
//
//
//所谓不可访问属性，实际上就是在调用某个属性时发现这个属性没有被定义或者不允许访问，这时候不同的操纵会触发不同的魔术方法



//__clone()
//


class MagicTest{
	//----1----
	//__tostring会在把对象转换为string的时候自动调用
	public function __tostring(){
		return 'This is the Class MagicTest<br/>';
	}

	//__invoke会在把对象当做一个方法调用的时候自动调用
	public function __invoke($x){
		echo '__invoke called with parameter'.$x.'<br/>';
	}

	//----2----
	//方法的重载
	//这个方法的参数第一个就是调用的方法的名称，第二个参数是方法调用的参数组成的数组
	public function __call($name,$arguments){
		echo 'Calling '.$name.' with parameters:'.implode(",",$arguments).'<br/>';
	}


	//静态方法的重载，注意这个方法需要设定为static
	public static function __callStatic($name,$arguments){
		echo 'Static calling '.$name.' with parameters:'.implode(',',$arguments).'<br/>';
	}


	//----3----
	public function __get($name){
		return 'Getting the property '.$name.'<br/>';
	}

	public function __set($name,$value){
		echo 'Setting the property '.$name.' to value '.$value.'<br/>';
	}

	public function __isset($name){
		echo '__isset invoked'.'<br/>';
		return true;
	}
	public function __unset($name){
		echo 'unsetting property '.$name.'<br/>';
	}
}

//----1----
$obj =new MagicTest();
echo $obj;//对象转换为string
$obj(5);//把对象当做一个方法调用


//----2----
$obj->runTest('para1','para2');
//在类定义外部访问静态 属性，我们可以用类名加::操作符的方法来访问类的静态成员
MagicTest::runTest('para1','para2');


//----3----
echo $obj->className;
$obj->className = 'MagicClassX';

echo '$obj->className is set? '.isset($obj->className).'<br/>';
echo '$obj->className is empty? '.empty($obj->className).'<br/>';
//????????

unset($obj->className);

?>